﻿namespace VoiceDominion
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Drawing;
    using System.Linq;
    using System.Reflection;
    using System.Threading;
    using System.Windows.Forms;

    public class VoiceDominionApp
    {
        static VoiceDominionApp()
        {
            Modules = new Dictionary<string, IModule>();
        }

        public static Dictionary<string, IModule> Modules { get; set; }

        private static System.Windows.Window LogWindow { get; set; }

        [STAThread]
        public static void Main()
        {
            var app = new App();

            using (var icon = CreateTrayIcon())
            {
                // http://stackoverflow.com/questions/699852/how-to-find-all-the-classes-which-implement-a-given-interface
                var moduleTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                                where t.GetInterfaces().Contains(typeof(IModule))
                                         && t.GetConstructor(Type.EmptyTypes) != null
                                      select t;

                foreach (var type in moduleTypes)
                {
                    Thread thread = new Thread(delegate()
                      {
                          var instance = Activator.CreateInstance(type) as IModule;
                          Modules.Add(type.Name, instance);
                      });
                    thread.Start();
                }

                Speech.Instance.Run();
                LogWindow = new MainWindow();

                if (bool.Parse(ConfigurationManager.AppSettings["ShowDebugWindowOnStartup"]))
                {
                    LogWindow.Show();
                }

                app.Run();
                Speech.Instance.Dispose();
                icon.Visible = false;
            }
        }

        public static NotifyIcon CreateTrayIcon()
        {
            var trayIcon = new NotifyIcon();
            trayIcon.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);

            trayIcon.ContextMenu = new ContextMenu(new MenuItem[]
            {
                new MenuItem(
                    "Exit Voice Dominion", 
                    (s, e) => 
                    {
                        trayIcon.Visible = false;
                        //// TODO: Why does App.Exit does not work?
                        Environment.Exit(0);
                    })
            });

            trayIcon.DoubleClick += delegate(object sender, EventArgs args)
            {
                LogWindow.Show();
            };

            trayIcon.Visible = true;
            return trayIcon;
        }
    }
}
